package com.itsu.job.rpc.request;

import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import com.itsu.job.components.Const;
import com.itsu.job.exception.JobException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Jerry.Su
 * @Date 2022/2/8 16:11
 */
@Slf4j
public class RpcRegisterRequestHandler extends JobRpcRequestHandler {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Map<String, Object> apply(String uri, String requestData) {
        Map<String, Object> params = parseParams(requestData);
        String registerAddress = (String) params.get("registerAddress");
        Assert.notNull(registerAddress, "can not register a job node with a null register address");
        Pattern pattern = Pattern.compile(Const.HTTP_URL_REGEX);
        Matcher matcher = pattern.matcher(registerAddress.trim());
        if (matcher.matches()) {
            String nodeStr = stringRedisTemplate.opsForValue().get(Const.REGISTER_RPC_NODES);
            nodeStr = nodeStr == null ? "" : nodeStr;
            String[] nodes = nodeStr.split(Const.RPC_NODE_SPLIT);
            if (!ArrayUtil.contains(nodes, registerAddress)) {
                if (!StringUtils.hasText(nodeStr)) {
                    nodeStr = registerAddress;
                } else {
                    nodeStr += Const.RPC_NODE_SPLIT + registerAddress;
                }
                stringRedisTemplate.opsForValue().set(Const.REGISTER_RPC_NODES, nodeStr);
                stringRedisTemplate.opsForValue().set(registerAddress, Const.UP_STATUS);
            } else {
                log.info("{} has already be registered", registerAddress);
            }
        } else {
            throw new JobException("not a valid http url for register address. [ " + registerAddress + " ]");
        }
        MapBuilder<String, Object> builder = MapUtil.builder();
        return builder.put("code", 0).build();
    }
}
